/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __X_BUG_H__
#define __X_BUG_H__

/* includes (standard library, system) ---------------------------------------*/
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/
#include <kconfig.h>

#ifdef CONFIG_KPRINTF
#include <kprintf.h>
#endif

#include <a_it.h>

/* includes (local) ----------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* defines -------------------------------------------------------------------*/
/* typedefs ------------------------------------------------------------------*/
/* macro ---------------------------------------------------------------------*/

/**
 * BUG - enter bug state
 *
 * usage: BUG(format, args), arguments is the same as kprintf
 */
#ifdef CONFIG_KPRINTF
#define BUG(...)                                                                                   \
    do {                                                                                           \
        /* disable interrupt to force kprintf use poll mode */                                     \
                                                                                                   \
        (void)it_lock();                                                                           \
                                                                                                   \
        kprintf("\nBUG, " __VA_ARGS__);                                                            \
                                                                                                   \
        kprintf("\n@ (file : %s, line : %d)", __FILE__, __LINE__);                                 \
                                                                                                   \
        __bug("");                                                                                 \
    } while (0)
#else
#define BUG(...)                                                                                   \
    do {                                                                                           \
        __bug("");                                                                                 \
    } while (0)
#endif

/**
 * BUG_ON - executive code and enter to bug state when the result is true
 *
 * code:   the code to executive, note, it will be executived always regardless
 *         to the macro of CONFIG_DEBUG, if the code is comperation only, compiler
 *         can do correct optimization
 *
 * examples:
 *
 *     BUG_ON(xxx != 0, "xxx is %d", xxx);
 *
 *     BUG_ON(xxx == 0, "xxx is not supported");
 */
#define BUG_ON(code, ...)                                                                          \
    do {                                                                                           \
        if (unlikely(code)) {                                                                      \
            BUG("\"" __CVTSTR_RAW(code) "\" unexpected!\n" __VA_ARGS__);                           \
        }                                                                                          \
    } while (0)

/* inlines -------------------------------------------------------------------*/
/* externs -------------------------------------------------------------------*/
void __bug(const char *info);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __X_BUG_H__ */
